package com.learn.xiaoha.sqlsession.factory;

import com.alibaba.druid.pool.DruidDataSource;
import com.learn.xiaoha.sqlsession.ProxyMapper.ProxyMapper;
import com.learn.xiaoha.sqlsession.SimpleSqlSession;
import com.learn.xiaoha.sqlsession.SqlSession;
import com.learn.xiaoha.sqlsession.entity.Book;
import com.learn.xiaoha.sqlsession.entity.Student;
import com.learn.xiaoha.sqlsession.mapper.BookMapper;
import com.learn.xiaoha.sqlsession.mapper.StudentMapper;
import com.learn.xiaoha.sqlsession.utils.ClazzUtils;
import com.learn.xiaoha.sqlsession.utils.JdbcExecute;
import org.apache.commons.lang3.ArrayUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * SimpleSqlSessionFactory
 *
 * @author: cyx_jay
 * @date: 2021/2/2 13:45
 */
public class SimpleSqlSessionFactory {

    /**
     * mapper文件所在的包
     */
    private String [] packNames;

    /**
     *数据源
     */
    private DataSource dataSource;
    /**
     * mapper Map
     */
    private Map<Class, Object> mapperMap;

    private Class sqlSessionImplClass;

    public SimpleSqlSessionFactory simpleSqlSessionFactory(){
        return new SimpleSqlSessionFactory();
    }

    public SimpleSqlSessionFactory build(DataSource dataSource){

        this.dataSource = dataSource;
        init();
        return this;
    }

    public SimpleSqlSessionFactory build(String... packNames){
        this.packNames = packNames;
        init();
        return this;
    }

    /**
     * @Description 初始化方法 主要是创建mapper代理对象
     * @Date 2021/2/2 13:57
     * @Param
     * @return
     */
    void init()  {
        DataSource dataSource = JdbcExecute.getDataSource();
        if (dataSource == null){
            JdbcExecute.setDataSource(this.dataSource);
        }
        JdbcExecute.simpleSqlSessionFactory = this;
        if (ArrayUtils.isNotEmpty(packNames) && this.dataSource != null){
            mapperMap = new HashMap<>(16);
            //产生全部的代理对象
            ProxyMapper proxyMapper = new ProxyMapper();
            for (String packName : packNames) {
                List<String> clazzNames = ClazzUtils.getClazzName(packName, false);
                if (clazzNames != null && !clazzNames.isEmpty()){
                    for (String clazzName : clazzNames) {
                        try {
                            Class<?> aClass = Class.forName(clazzName);
                            Object proxyMapperObj = proxyMapper.getProxyMapper(aClass);
                            mapperMap.put(aClass,proxyMapperObj);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }

        }
    }


    public static void main(String[] args) throws Exception {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl("jdbc:mysql://127.0.0.1/vhr?serverTimezone=UTC");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("cyx520slm");
        druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        SimpleSqlSessionFactory simpleSqlSessionFactory = new SimpleSqlSessionFactory();
        SimpleSqlSessionFactory sqlSessionFactory = simpleSqlSessionFactory.build(druidDataSource).build("com.learn.xiaoha.sqlsession.mapper");
        SqlSession sqlSession = sqlSessionFactory.getSqlSession();

        BookMapper mapper = sqlSession.getMapper(BookMapper.class);
        List<Book> all = mapper.findAll();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.findAll();
        sqlSession.startTransaction();
        Book book = new Book();
        book.setBookname("简爱6");
        book.setPrice(100);
        book.setHrid(4);
        mapper.insert(book);
        int c = 1/0;
        Student student = new Student();
        student.setLover("陈6");
        student.setName("hh6");
        studentMapper.insert(student);
        sqlSession.commit();
        sqlSession.close();


    }

    public SqlSession getSqlSession(){

        if (sqlSessionImplClass == null){
            SimpleSqlSession simpleSqlSession = new SimpleSqlSession(this);
            SqlSession simpleSqlSessionThread = JdbcExecute.sqlSessionThreadLocal.get();
            if (simpleSqlSessionThread == null){
                JdbcExecute.sqlSessionThreadLocal.set(simpleSqlSession);
            }
            try {
                simpleSqlSession.setConnection(this.dataSource.getConnection());
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            return simpleSqlSession;
        }
        return null;
    }


    public String[] getPackNames() {
        return packNames;
    }

    public void setPackNames(String[] packNames) {
        this.packNames = packNames;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Map<Class, Object> getMapperMap() {
        return mapperMap;
    }

    public void setMapperMap(Map<Class, Object> mapperMap) {
        this.mapperMap = mapperMap;
    }

    public Class getSqlSessionImplClass() {
        return sqlSessionImplClass;
    }

    public void setSqlSessionImplClass(Class sqlSessionImplClass) {
        this.sqlSessionImplClass = sqlSessionImplClass;
    }
}
